/**
 * 照相
 */
<template>
<vp-dialog ref="editDialogRef" :span="2" :showCancel="false" :before-close="handleBeforeClose">
    <template #title>
        <vp-label zh="拍照" en="Take Photo"/>
    </template>
    <vp-card v-loading="loading" element-loading-text="初始化摄像头中..." :body-style="{textAlign: 'center'}">
            <!-- 画笔控件 用来拍照 -->
        <canvas style="display: none" ref="canvasDom"></canvas>
        <!-- 播放器，用来播放拍摄的视频 -->
        <video v-show="!imgurl" class="camera_video" ref="videoDom"></video>
        <!--  显示照片  -->
        <img v-show="imgurl" :src="imgurl" />
    </vp-card>
    <template #footer>
        <vp-btn-cancel @click="handleClose"/>
        <vp-btn type="primary" v-if="!imgurl" @click="takePhoto">
            <vp-label zh="拍照" en="Take Photo"/>
        </vp-btn>
        <vp-btn type="warning" v-if="imgurl" @click="takePhoto">
            <vp-label zh="重拍" en="Retake Photo"/>
        </vp-btn>
        <vp-btn-confirm v-if="imgurl" @click="handleConfirm"/>
    </template>
</vp-dialog>
</template>
<script setup>
import { ref, nextTick } from "vue";
import request from '/@/utils/request';
import { formatDate } from '/@/utils/formatTime';

// canvas控件对象
const canvasDom = ref(null);
// video 控件对象
const videoDom = ref(null);
// 照片路径
const imgurl = ref(null);

const callback = ref((data)=>{});

const emits = defineEmits(['save']);
const editDialogRef = ref();
const loading = ref(false);

// 显示
const handleOpen =(param) => {
    if (param.callback && typeof param.callback === "function") {
        callback.value = param.callback;
    }
    imgurl.value = ''
    editDialogRef.value.handleOpen();
    openCamera();
}

// 关闭
function handleClose() {
    stop();
    nextTick(() => {
        editDialogRef.value.handleClose();
    })
}

const openCamera = () => {
    // 检测浏览器是否支持mediaDevices
    if (navigator.mediaDevices) {
        loading.value = true;
        navigator.mediaDevices
        // 开启视频，关闭音频
        .getUserMedia({audio: false, video: true})
        .then((stream) => {
            loading.value = false;
            // 将视频流传入viedo控件
            videoDom.value.srcObject = stream;
            // 播放
            videoDom.value.play();
        })
    .catch((err) => {
        console.log(err);
    });
    } else {
    window.alert("该浏览器不支持开启摄像头，请更换最新版浏览器");
    }
};

// 拍照
const takePhoto = () => {
    // 如果已经拍照了就重新启动摄像头
    if (imgurl.value) {
        imgurl.value = null;
        openCamera()
        return;
    }

    // 设置画布大小与摄像大小一致
    canvasDom.value.width = videoDom.value.videoWidth;
    canvasDom.value.height = videoDom.value.videoHeight;
    // 执行画的操作
    canvasDom.value.getContext("2d").drawImage(videoDom.value, 0, 0);
    // 将结果转换为可展示的格式
    imgurl.value = canvasDom.value.toDataURL("image/jpg");
    // 关闭摄像头
    stop();
}

// 确定
const handleConfirm = () => {
    if (imgurl.value) {
        var formData = new FormData();
        const file = dataURLtoFile(imgurl.value, new Date().getTime() + '.jpg')
        formData.append('file', file);
        request.post("/file/upload", formData, {
            headers: { 
            'content-type': 'multipart/form-data',
        },
        }).then((res) => {
            callback.value(res.data[0]);
            // 关闭
            handleClose();
        }).catch();
    }
}

// 关闭摄像头
const stop = () => {
    let stream = videoDom.value.srcObject;
    if (!stream) return;
    let tracks = stream.getTracks();
    tracks.forEach((x) => {
        x.stop();
    });
};

const dataURLtoFile  = (dataURL, filename) => {
    const arr = dataURL.split(',')
      const mime = arr[0].match(/:(.*?);/)[1]
      const bstr = atob(arr[1])
      let n = bstr.length
      const u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: mime })
}

const handleBeforeClose = (done) => {
    stop();
    done();
}

defineExpose({
    handleOpen,
    handleClose
});
</script>
<style lang="scss" scoped>
</style>